package uml.view;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.Border;

import uml.eventsystem.IObserver;
import uml.eventsystem.ISubject;
import uml.eventsystem.SubjectImpl;
import uml.eventsystem.events.UMLEventId;
import uml.objects.UMLObject;
import uml.util.UMLConstants;
import uml.util.listeners.DragListener;
import uml.util.listeners.Dragable;

/**
 * The super class for all UMLContainerView objects.
 * 
 * @author Evan Curtis and Neil Obetz
 *
 */
public class UMLContainerView
		extends JPanel
		implements UMLObject, MouseListener, MouseMotionListener, ISubject
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 9214675205263893993L;
	/**
	 * Creates a default UMLContainerView.
	 */	
	private Integer m_layer;
	private UMLEventId m_eventId = null;
	private Border m_border;
	
	
	SubjectImpl m_subjectImplementation;
	
	public UMLContainerView ()
	{
		m_subjectImplementation = new SubjectImpl(this);
		setLayout (new BorderLayout ());
	}

	@Override
	public Component getComponent() 
	{
		return this;
	}

	@Override
	public void translate(Point dp) 
	{
		//gets the width and height of the DiagramPanel
		int parentWidth = this.getParent().getWidth();
		int parentHeight = this.getParent().getHeight();
		
		//calculates new position
		Point newLocation = new Point();
		newLocation.x = (int)(this.getX() + dp.getX());
		newLocation.y = (int)(this.getY() + dp.getY());
		
		//checks if new position is within the DiagramPanel
		if ((newLocation.x + this.getWidth() < parentWidth) && (newLocation.y + this.getHeight() < parentHeight) &&
			(newLocation.x > 0) && (newLocation.y > 0)) {
				this.setLocation(newLocation);
				this.notifyObservers(UMLEventId.TRANSLATE);
		}
	}

	@Override
	public Integer getLayer() 
	{
		return m_layer;
	}

	@Override
	public void setLayer(Integer layer) 
	{
		this.m_layer = layer;
	}
	public String[] getText()
	{
		ArrayList<String> text = new ArrayList<String>();
		Component[] components = this.getComponents();
		for(Component c : components)
			if(c instanceof JTextArea)
				text.add(((JTextArea)c).getText());
		//return (String[]) text.toArray();
		return null;
	}

	@Override
	public void registerObserver(IObserver observer) 
	{
		
	}

	@Override
	public void mouseClicked(MouseEvent event) 
	{
		if(event.getClickCount() == 2)//double click
		{
			Object source = event.getSource();
			if(source instanceof Component)
			{
				Component c = (Component)source;
				//System.out.println(c.getFocusCycleRootAncestor());
				c.requestFocus();
			}
		}
		event.setSource(this);
		this.dispatchEvent(event);
	}

	@Override
	public void mouseEntered(MouseEvent e) 
	{
		e.setSource(this);
		this.dispatchEvent(e);
	}

	@Override
	public void mouseExited(MouseEvent e) 
	{
		e.setSource(this);
		this.dispatchEvent(e);
	}

	@Override
	public void mousePressed(MouseEvent e) 
	{
		e.setSource(this);
		this.dispatchEvent(e);	
	}

	@Override
	public void mouseReleased(MouseEvent e) 
	{
		e.setSource(this);
		this.dispatchEvent(e);
	}

	@Override
	public void mouseDragged(MouseEvent e) 
	{
		e.setSource(this);
		this.dispatchEvent(e);		
	}

	@Override
	public void mouseMoved(MouseEvent e) 
	{
		e.setSource(this);
		this.dispatchEvent(e);
	}

	@Override
	public void addObserver(IObserver observer, UMLEventId eventId) 
	{
		m_subjectImplementation.addObserver(observer, eventId);
	}

	@Override
	public void removeObserver(IObserver observer, UMLEventId eventId) 
	{
		m_subjectImplementation.removeObserver(observer, eventId);
	}

	@Override
	public void notifyObservers(UMLEventId eventId) 
	{
		m_subjectImplementation.notifyObservers(eventId);
	}

	@Override
	public void select() 
	{
		this.setBorder(UMLConstants.CLASS_SELECTED_BORDER);
	}

	@Override
	public void unselect() 
	{
		this.setBorder(m_border);
	}

	@Override
	public UMLEventId getEventId() {
		// TODO Auto-generated method stub
		return m_eventId;
	}
	
	public void setInactiveBorder(Border border)
	{
		m_border = border;
	}

	public void setEventId(UMLEventId event) 
	{
		m_eventId = event;
	}
}
